package edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtext.client.core.Function;

import edu.stanford.bmir.protege.web.client.project.Project;
import edu.stanford.bmir.protege.web.client.rpc.stkosutil.mapper.CancelMapperResult;
import edu.stanford.bmir.protege.web.client.rpc.stkosutil.mapper.MappingResult;
import edu.stanford.bmir.protege.web.client.ui.library.msgbox.MessageBox;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.common.GWTExtUtil;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.common.StkosPanelType;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.common.interfaces.StkosCallBack;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.according.StkosMapperAccordingProjectDescriptionPortlet;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.according.StkosMapperAccordingProjectTreePortlet;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.common.StkosMapperConstant;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.current.StkosMapperCurrentProjectDescriptionPortlet;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.current.StkosMapperCurrentProjectTreePortlet;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.option.StkosMapperOptionPortlet;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.option.StkosMapperOptionView.StkosMapperOptionViewButtonType;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.option.StkosMapperOptionView.StkosMapperOptionViewListBoxType;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.statistical.StkosMapperStatisticalPortlet;
import edu.stanford.bmir.protege.web.client.ui.tab.AbstractTab;
import edu.stanford.bmir.protege.web.shared.project.ProjectDetails;

/**
 * stkos mapper tab
 * 
 * @author LWS
 * 
 */
@SuppressWarnings("unchecked")
public class StkosMapperTab extends AbstractTab {

	/** Column 1 **/
	// Row 1--- 本体映射选项
	private StkosMapperOptionPortlet optionPortlet;

	// Row 2--- 当前本体树
	private StkosMapperCurrentProjectTreePortlet currentProjectTreePortlet;

	// Row 3--- 当前本体描述
	private StkosMapperCurrentProjectDescriptionPortlet currentProjectDescriptionPortlet;

	/** Column 2 **/
	// Row 1--- 统计结果
	private StkosMapperStatisticalPortlet statisticalPortlet;

	// Row 2--- 参照本体树
	private StkosMapperAccordingProjectTreePortlet accordingProjectTreePortlet;

	// Row 3--- 参照本体描述
	private StkosMapperAccordingProjectDescriptionPortlet accordingProjectDescriptionPortlet;

	public StkosMapperTab(Project project) {
		super(project);
	}

	@Override
	public void setup() {
		super.setup();
		setLabel("映射工具");

		optionPortlet = (StkosMapperOptionPortlet) getPortletByClassName(StkosMapperOptionPortlet.class
				.getName());
		currentProjectTreePortlet = (StkosMapperCurrentProjectTreePortlet) getPortletByClassName(StkosMapperCurrentProjectTreePortlet.class
				.getName());
		currentProjectDescriptionPortlet = (StkosMapperCurrentProjectDescriptionPortlet) getPortletByClassName(StkosMapperCurrentProjectDescriptionPortlet.class
				.getName());

		statisticalPortlet = (StkosMapperStatisticalPortlet) getPortletByClassName(StkosMapperStatisticalPortlet.class
				.getName());
		accordingProjectTreePortlet = (StkosMapperAccordingProjectTreePortlet) getPortletByClassName(StkosMapperAccordingProjectTreePortlet.class
				.getName());
		accordingProjectDescriptionPortlet = (StkosMapperAccordingProjectDescriptionPortlet) getPortletByClassName(StkosMapperAccordingProjectDescriptionPortlet.class
				.getName());

		if (optionPortlet == null || currentProjectTreePortlet == null
				|| currentProjectDescriptionPortlet == null
				|| statisticalPortlet == null
				|| accordingProjectTreePortlet == null
				|| accordingProjectDescriptionPortlet == null) {
			return;
		}

		setControllingPortlet(optionPortlet);

		registerOptionViewEventHandler();
		registerTreeEventHandler();
	}

	protected void registerOptionViewEventHandler() {
		// ListBox accordingOntolgoies change handler
		StkosCallBack accordingOntolgoyCB = new StkosCallBack() {
			@Override
			public void onCallBack(Object... objects) {
				ProjectDetails pd = optionPortlet.getOptionView()
						.getSelectedProjectDetails();
				if (pd == null) {
					updateAccordingProject(null);
				} else {
					AsyncCallback<Project> callback = new AsyncCallback<Project>() {
						@Override
						public void onFailure(Throwable caught) {
							updateAccordingProject(null);
						}

						@Override
						public void onSuccess(Project result) {
							updateAccordingProject(result);
						}
					};
					GWTExtUtil.getProject(pd, callback);
				}
			}
		};
		optionPortlet.getOptionView().setListBoxHandler(
				StkosMapperOptionViewListBoxType.ACCORDINGONTOLOGY,
				accordingOntolgoyCB);
		// button autoMapper click handler
		StkosCallBack autoMapperCB = new StkosCallBack() {
			@Override
			public void onCallBack(Object... objects) {
				MappingResult mappingResult = null;
				if (objects == null || objects.length == 0
						|| objects[0] == null) {
					MessageBox.showAlert("提示", "自动匹配返回结果为空!");
				} else {
					currentProjectTreePortlet.onRefresh();
					currentProjectDescriptionPortlet.onRefresh();
					accordingProjectTreePortlet.onRefresh();
					accordingProjectDescriptionPortlet.onRefresh();

					mappingResult = (MappingResult) objects[0];
				}
				statisticalPortlet.getStatisticalView().setMappingResult(
						mappingResult);
			}
		};
		optionPortlet.getOptionView().setBtnHandler(
				StkosMapperOptionViewButtonType.AUTOMATCH, autoMapperCB);
		// button showClassMapperResult click handler
		StkosCallBack showClassMapperResultCB = new StkosCallBack() {
			@Override
			public void onCallBack(Object... objects) {
				currentProjectTreePortlet.showPanel(StkosPanelType.CLASS_TREE);
				updateCurrentProjectDescriptionPortletTreeNode();

				accordingProjectTreePortlet
						.showPanel(StkosPanelType.CLASS_TREE);
				updateAccordingProjectDescriptionPortletTreeNode();
			}
		};
		optionPortlet.getOptionView().setBtnHandler(
				StkosMapperOptionViewButtonType.SHOWCLASSMAPPERRESULT,
				showClassMapperResultCB);
		// button showPropertyMapperResult click handler
		StkosCallBack showPropertyMapperResultCB = new StkosCallBack() {
			@Override
			public void onCallBack(Object... objects) {
				currentProjectTreePortlet
						.showPanel(StkosPanelType.PROPERTY_TREE);
				updateCurrentProjectDescriptionPortletTreeNode();

				accordingProjectTreePortlet
						.showPanel(StkosPanelType.PROPERTY_TREE);
				updateAccordingProjectDescriptionPortletTreeNode();
			}
		};
		optionPortlet.getOptionView().setBtnHandler(
				StkosMapperOptionViewButtonType.SHOWPROPERTYMAPPERSULT,
				showPropertyMapperResultCB);
		// button exportResult click handler
		StkosCallBack exportResultCB = new StkosCallBack() {
			@Override
			public void onCallBack(Object... objects) {
				// MessageBox.showAlert("exportResultCB");
			}
		};
		optionPortlet.getOptionView().setBtnHandler(
				StkosMapperOptionViewButtonType.EXPORTRESULT, exportResultCB);
		// button cancle click handler
		StkosCallBack cancleCB = new StkosCallBack() {
			@Override
			public void onCallBack(Object... objects) {
				// MessageBox.showAlert("cancleCB");
				CancelMapperResult result = null;
				try {
					result = (CancelMapperResult) objects[0];
				} catch (Exception e) {
				}

				currentProjectTreePortlet.onRefresh();
				currentProjectDescriptionPortlet.onRefresh();
				accordingProjectTreePortlet.onRefresh();
				accordingProjectDescriptionPortlet.onRefresh();
				statisticalPortlet.getStatisticalView().setMappingResult(null);
			}
		};
		optionPortlet.getOptionView().setBtnHandler(
				StkosMapperOptionViewButtonType.CANCEL, cancleCB);
	}

	protected void registerTreeEventHandler() {
		accordingProjectTreePortlet.addListener(
				GWTExtUtil.EVENT_ONSELECTIONCHANGE, new Function() {
					@Override
					public void execute() {
						updateAccordingProjectDescriptionPortletTreeNode();
					}
				});

		accordingProjectTreePortlet.addListener(GWTExtUtil.EVENT_ONDBLCLICK,
				new Function() {
					@Override
					public void execute() {
						useAccordingProjectTreePanelMappingNo();
					}
				});

		currentProjectTreePortlet.addListener(
				GWTExtUtil.EVENT_ONSELECTIONCHANGE, new Function() {
					@Override
					public void execute() {
						updateCurrentProjectDescriptionPortletTreeNode();
					}
				});

		currentProjectTreePortlet.addListener(GWTExtUtil.EVENT_ONDBLCLICK,
				new Function() {
					@Override
					public void execute() {
						useCurrentProjectTreePanelMappingNo();
					}
				});
	}

	protected void updateAccordingProjectDescriptionPortletTreeNode() {
		accordingProjectDescriptionPortlet.setSelectedTreeNode(
				accordingProjectTreePortlet.getActivityPanel(),
				accordingProjectTreePortlet.getSelectedTreeNode());
	}

	protected void updateCurrentProjectDescriptionPortletTreeNode() {
		currentProjectDescriptionPortlet.setSelectedTreeNode(
				currentProjectTreePortlet.getActivityPanel(),
				currentProjectTreePortlet.getSelectedTreeNode());
	}

	protected void updateAccordingProject(Project accordingProject) {
		accordingProjectTreePortlet.setAccordingProject(accordingProject);
		accordingProjectDescriptionPortlet
				.setAccordingProject(accordingProject);

		currentProjectTreePortlet.setAccordingProject(accordingProject);
	}

	protected void useAccordingProjectTreePanelMappingNo() {
		Integer mappingNo = null;
		try {
			mappingNo = Integer.parseInt(accordingProjectTreePortlet
					.getSelectedTreeNode().getAttribute(
							StkosMapperConstant.STKOSMAPPERVALUEPREFIX));
		} catch (Exception e) {
			// GWT.log("Getting according project selected node mappingNo failure.",e);
		}
		accordingProjectTreePortlet.removeHighlight(accordingProjectTreePortlet
				.getHighlight());
		currentProjectTreePortlet.searchMappingNo(mappingNo);
	}

	protected void useCurrentProjectTreePanelMappingNo() {
		Integer mappingNo = null;
		try {
			mappingNo = Integer.parseInt(currentProjectTreePortlet
					.getSelectedTreeNode().getAttribute(
							StkosMapperConstant.STKOSMAPPERVALUEPREFIX));
		} catch (Exception e) {
			// GWT.log("Getting current project selected node mappingNo failure.",e);
		}
		currentProjectTreePortlet.removeHighlight(currentProjectTreePortlet
				.getHighlight());
		accordingProjectTreePortlet.searchMappingNo(mappingNo);
	}
}